home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Best of MacTutor - S…e Code for Volumes 1 to 5
/
The Best of MacTutor - Source Code for Volume 1-5 (Wayzata Technology)(6031)(1990).bin
/
Source Code
/
#26 (Nov 87)
/
asm lab Formatter
/
FormNumString.asm
< prev
next >
Wrap
Assembly Source File
|
1987-10-21
|
4KB
|
166 lines
; FormNumString.asm
;-------------------
; by Mike™ Scanlin 29 Dec 1986
Xref FormNumString,GetANumber
;============
FormNumString
;============
; format the string representation of a number (integer or real)
; according to a format string.
; input: A0 points to string of a number (which should be in a
; space big enough for formatting result)
; A1 points to format string
; syntax of format string is [',']d[d]['.'[d[d]]] where ''
; denote a constant char and d denotes a digit '0'..'9'
; there is no length byte for these strings.
; valid strings invalid strings
; 3 230. (230 too big [99 max])
; 4.0 or 4. .0 (need a d before '.')
; ,3.4 ,.4 (need a d between ',.')
; ,12.20 0.123 (123 too big)
; output: A0 points to formatted string of a number
; A1 points to first byte after format string
MOVEM.L D0-D5/A2,-(SP)
CMPI.B #',',(A1)
BNE.S @6
ADDA #1,A1
;do commas
;first find out if there is a decimal point in the string
MOVEQ #0,D0
MOVE.B (A0),D0 ;length of string
MOVE D0,D2 ;save in case it's and int
SUBQ #1,D0 ;loop control
;D0 counts how many digits from the end of the string to the
;decimal point (including the decimal point -- which is why
;it starts out as 1 and not 0). If the number is an int, then D0=0
MOVEQ #1,D1
@1 CMPI.B #'.',1(A0,D0) ;find a dec point, it's a real
BEQ.S @2
ADDQ #1,D1
DBRA D0,@1
;it's an integer
MOVE D2,D0
MOVEQ #0,D1
;now add some commas
@2 MOVE D1,D5 ;save length of fraction
MOVEQ #3,D2 ;# of digits until next comma
SUBQ #1,D0
@3 ADDQ #1,D1 ;total len, from end to cur pos
SUBQ #1,D2
BNE.S @5
MOVE D0,D3
MOVE.B (A0,D0),D0
BSR IsItADigit ;test next digit
BNE.S @6
MOVE D3,D0
;move some chars, add a comma, increase string length.
MOVE D1,D4 ;loop control
SUBQ #1,D4
LEA 1(A0,D0),A2
@4 MOVE.B (A2,D4),1(A2,D4)
DBRA D4,@4
MOVE.B #',',(A2)
ADDI.B #1,(A0)
ADDQ #1,D1 ;for the comma
MOVEQ #3,D2 ;reset counter
@5 DBRA D0,@3
;get next byte of format string
@6 BSR.S GetANumber ;D0 = q
BMI.S @16 ;no q provided -- leave
MOVEQ #0,D2
MOVE.B (A0),D2 ;length of string
MOVE D2,D1
SUB D5,D1 ;D1=len of quotient now
SUB D1,D0
BMI.S @10
BEQ.S @10
ADD.B D0,(A0) ;increase length by D0 spaces
;add D0 # of preceeding spaces
@7 LEA 1(A0,D0),A2
SUBQ #1,D2
@8 MOVE.B 1(A0,D2),(A2,D2)
DBRA D2,@8
SUBQ #1,D0
@9 MOVE.B #' ',1(A0,D0)
DBRA D0,@9
;do remainder
@10 CMPI.B #'.',(A1)
BNE.S @16
ADDA #1,A1
;make sure there is a decimal point already
LEA 1(A0),A2
MOVEQ #0,D0
MOVE.B (A0),D0
SUBQ #1,D0
@11 CMP.B #'.',(A2)+
BEQ.S @12
DBRA D0,@11
MOVE.B #'.',(A2)+
ADD.B #1,(A0)
@12 BSR.S GetANumber
BMI.S @16 ;no r provided -- leave
;D0 is how many digits they want. D5 is what we've already got.
@13 SUBQ #1,D5
@14 CMP D5,D0
BEQ.S @16
BPL.S @15
SUB.B #1,(A0)
BRA.S @13
@15 MOVE.B #'0',(A2,D5) ;add a zero
ADD.B #1,(A0)
ADDQ #1,D5
BRA.S @14
@16 MOVEM.L (SP)+,A2/D0-D5
RTS
;=========
GetANumber
;=========
; convert a one or two digit ASCII integer into its numerical form
; input: A1 points to digit(s)
; output: D0 is the decimal equivalent (-1 if A1 didn't point to a digit)
; A1 points to byte after digit(s)
; Z and N flags reflect the value of D0
MOVEM.L D1-D2,-(SP)
MOVEQ #0,D0
MOVE.B (A1),D0
@1 BSR.S IsItADigit
BEQ.S @2
MOVEQ #-1,D0
BRA.S @4
@2 ADDA #1,A1
MOVE D0,D1 ;save first digit
MOVE.B (A1),D0
BSR.S IsItADigit
BEQ.S @3
MOVE D1,D0
BRA.S @4
@3 ADDA #1,A1
ADD D1,D1 ;multiply first digit by 10
MOVE D1,D2
ADD D2,D2
ADD D2,D2
ADD D2,D1
ADD D1,D0 ;add to second digit
@4 MOVEM.L (SP)+,D1-D2
TST D0
RTS
;=========
IsItADigit
;=========
; If the ASCII byte in D0 is in '0'..'9' it's value [0..9]
; is returned in D0. If D0 is a digit, all flags are set.
CMPI.B #'0',D0
BLT.S @1
CMPI.B #'9',D0
BGT.S @1
SUBI.B #'0',D0
MOVE #-1,CCR ;set all flags
RTS
@1 MOVE #0,CCR ;clear all flags
RTS